﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Interactivity;
using System.Reflection;
using System.Diagnostics;

namespace OpenLightGroup.Common.Behaviors
{
    //
    // If you want your Action to target elements other than its parent, extend your class
    // from TargetedTriggerAction instead of from TriggerAction
    //
    public class SetPropertyValueAction : TriggerAction<DependencyObject>
    {
        public SetPropertyValueAction()
        {
            // Insert code required on object creation below this point.
        }




        public object TargetObject
        {
            get { return (object)GetValue(TargetObjectProperty); }
            set { SetValue(TargetObjectProperty, value); }
        }

        // Using a DependencyProperty as the backing store for TargetObject.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TargetObjectProperty =
            DependencyProperty.Register("TargetObject", typeof(object), typeof(SetPropertyValueAction), new PropertyMetadata(null));



        public string PropertyName
        {
            get { return (string)GetValue(PropertyNameProperty); }
            set { SetValue(PropertyNameProperty, value); }
        }

        // Using a DependencyProperty as the backing store for PropertyName.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PropertyNameProperty =
            DependencyProperty.Register("PropertyName", typeof(string), typeof(SetPropertyValueAction), new PropertyMetadata(null));




        public object Value
        {
            get { return (object)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Value.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(object), typeof(SetPropertyValueAction), new PropertyMetadata(null));




        protected override void Invoke(object o)
        {


            PropertyInfo property = TargetObject.GetType().GetProperty(this.PropertyName);

            Type targetPropertyType = property.GetValue(this.TargetObject, null).GetType();

            if (targetPropertyType is Object || targetPropertyType == this.Value.GetType())
            {
                property.SetValue(this.TargetObject, this.Value, null);

            }
            else
            {
                object convertedValue = null;

                try
                {

                    convertedValue = Convert.ChangeType(this.Value, targetPropertyType, null);
                    property.SetValue(this.TargetObject, convertedValue, null);

                }
                catch (Exception ex)
                {

                    Debug.WriteLine("Could not convert value of type " + this.Value.GetType().ToString() + " to " + targetPropertyType.ToString());
                    Debug.WriteLine(ex.Message);

                    //convertedValue = null;
                }

                //if (convertedValue != null)
                //{
                //    property.SetValue(this.TargetObject, convertedValue, null);

                //}

            }

        }
    }
}